package com.lwl.mini.session;

import com.lwl.mini.exceptions.ExceptionFactory;
import com.lwl.mini.executor.Executor;
import com.lwl.mini.mapping.Environment;
import com.lwl.mini.transaction.DefaultTransactionFactory;
import com.lwl.mini.transaction.Transaction;
import com.lwl.mini.transaction.TransactionFactory;
import com.lwl.mini.transaction.TransactionIsolationLevel;

import java.sql.SQLException;

/**
 * @author lwl
 * @create 2022/4/12 8:57
 */
public class DefaultSqlSessionFactory implements SqlSessionFactory{

    private Configuration configuration;

    public DefaultSqlSessionFactory(Configuration configuration){
        this.configuration = configuration;
    }

    @Override
    public SqlSession openSession() {
        return openSession(true);
    }

    @Override
    public SqlSession openSession(boolean autoCommit){
        return openSessionByDataSourceOrJDBC(autoCommit,null);
    }

    @Override
    public SqlSession openSessionByDataSourceOrJDBC(boolean autoCommit, TransactionIsolationLevel level) {
        Transaction transaction = null;
        try {
            Environment environment = configuration.getEnvironment();
            TransactionFactory transactionFactory = getTransactionFactory();
            boolean userDruid = configuration.getSettings().get("userDruid");
            if(userDruid){
                //使用Druid连接池
                transaction = transactionFactory.newTransaction(environment.getDataSource(),autoCommit,level);
            }else{
                //使用默认JDBC操作
                transaction = transactionFactory.newTransaction(environment.getConnection(),autoCommit,level);
            }
            Executor executor = configuration.newExecutor(transaction);
            return new DefaultSqlSession(configuration,executor,autoCommit);
        } catch (Exception e) {
            closeTransaction(transaction);
            throw ExceptionFactory.wrapException("Error opening session.  Cause: " + e, e);
        }
    }

    private void closeTransaction(Transaction transaction) {
        if(transaction != null){
            try {
                transaction.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }


    public TransactionFactory getTransactionFactory() {
        return DefaultTransactionFactory.getInstance();
    }
}
